package com.xxwy.dependency.lookup;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author wy
 * @date 2020/4/22 16:05
 */
public class HierarchicalDependencyDemo {

  public static void main(String[] args) {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
    applicationContext.register(HierarchicalDependencyDemo.class);

    //1.获取HierarchicalBeanFactory<--ConfigurableListableBeanFactory

    ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
    System.out.println("当前BeanFactory 的父接口：" + beanFactory.getParentBeanFactory());
    BeanFactory parentBeanFactory = createParentBeanFactory();
    beanFactory.setParentBeanFactory(parentBeanFactory);
    System.out.println("当前BeanFactory 的父接口：" + beanFactory.getParentBeanFactory());

    applicationContext.refresh();
    displayContainsLocalBean(beanFactory, "user"); //false
    displayContainsBean(beanFactory, "user"); //true

    applicationContext.close();

  }


  private static void displayContainsBean(HierarchicalBeanFactory beanFactory, String beanName) {
    boolean b = containsBean(beanFactory, beanName);
    System.out.printf("当前%s 是否包含Bean %s : %s \n", beanFactory, beanName, b);

  }


  private static boolean containsBean(HierarchicalBeanFactory beanFactory, String beanName) {
    BeanFactory parentBeanFactory = beanFactory.getParentBeanFactory();
    if (parentBeanFactory instanceof HierarchicalBeanFactory) {
      HierarchicalBeanFactory factory = HierarchicalBeanFactory.class.cast(parentBeanFactory);
      if (containsBean(factory, beanName)) {
        return true;
      }
    }
    return beanFactory.containsLocalBean(beanName);
  }

  private static void displayContainsLocalBean(HierarchicalBeanFactory beanFactory, String beanName) {
    System.out.printf("当前%s 是否包含localBean %s : %s \n", beanFactory, beanName, beanFactory.containsLocalBean(beanName));
  }


  private static BeanFactory createParentBeanFactory() {
    DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader definitionReader = new XmlBeanDefinitionReader(factory);

    int definitions = definitionReader.loadBeanDefinitions("classpath:/META-INF/dependency-lookup-context.xml");
    System.out.println(definitions);
    return factory;
  }
}
